﻿/*
/**
 * This is an example of instantiating the various parts of the state engine.
 * The actual state machine is nonsense -- the purpose of the example is to show
 * how things fit together.  It was created using FlashDevelop 3.0.
 */

package 
{
	import com.flashsim.FStEng.Three.Transition;
	import flash.display.Sprite;
	import flash.display.MovieClip;
	import com.flashsim.FStEng.Three.HState;
	import com.flashsim.FStEng.Three.HStateC;
	import com.flashsim.FStEng.Three.State;
	import com.flashsim.FStEng.Three.StateManager;
	import flash.events.Event;
	import com.flashsim.FStEng.Three.StateEngine;
	import com.flashsim.FStEng.Three.EventWithData;
	import com.flashsim.FStEng.Three.PulseActivity;
	import flash.utils.getTimer;
	
	public class Main extends Sprite 
	{
		
		public var se:StateEngine;
		
		private var FirstMachineOutput:Array = ["******** ENGINE EVENT ACTIVATE",
												"WE ENTERED state <TOP_CONTAINER_STATE>",
												"WE ENTERED state <ON>",
												"WE ENTERED state <ON 0>",
												"WE ENTERED state <ON5>",
												"State <ON 0> Caught event: RANDOM",
												"FINISHED POSTING EVENTS",
												"PULSE <ON 0>",
												"State <ON5> Caught event: RANDOM5",
												"WE LEFT state <ON 0>",
												"ON 0 -> ON1 on Event: RANDOM5",
												"WE ENTERED state <ON1>",
												"WE LEFT state <ON1>",
												"ON1 -> ON2 on Event: BOOGA-BOOGA",
												"WE ENTERED state <ON2>",
												"WE LEFT state <ON2>",
												"WE LEFT state <ON5>",
												"WE LEFT state <ON>",
												"ON2 transition to OFF 0, Event: AFTER BOOGA-BOOGA",
												"WE ENTERED state <OFF>",
												"WE ENTERED state <OFF0>",
												"WE LEFT state <OFF0>",
												"WE LEFT state <OFF>",
												"topContainerState transition to ON's History, Event: REALLY AFTER AFTER BOOGA-BOOGA",
												"WE ENTERED state <ON>",
												"WE ENTERED state <ON2>",
												"WE ENTERED state <ON5>",
												"WE LEFT state <ON2>",
												"WE LEFT state <ON5>",
												"WE LEFT state <ON>",
												"WE LEFT state <TOP_CONTAINER_STATE>",
												"******** ENGINE EVENT DEACTIVATE",
												"EVENT NOT HANDLED: [Event type=\"TEST COMPLETE\" bubbles=false cancelable=false eventPhase=2]"
					 ];

		private var OutputLog:Array;
		private var SamekTestOutput:Array = ["WE ENTERED state <s0>",
											"WE ENTERED state <s1>",
											"WE ENTERED state <s11>",
											"POSTING EVENT (A)",
											"WE LEFT state <s11>",
											"WE LEFT state <s1>",
											"WE ENTERED state <s1>",
											"WE ENTERED state <s11>",
											"POSTING EVENT (B)",
											"POSTING EVENT (C)",
											"WE LEFT state <s11>",
											"WE LEFT state <s1>",
											"WE ENTERED state <s2>",
											"WE ENTERED state <s21>",
											"WE ENTERED state <s211>",
											"POSTING EVENT (D)",
											"WE LEFT state <s211>",
											"WE ENTERED state <s211>",
											"POSTING EVENT (E)",
											"POSTING EVENT (F)",
											"WE LEFT state <s211>",
											"WE LEFT state <s21>",
											"WE LEFT state <s2>",
											"WE ENTERED state <s1>",
											"WE ENTERED state <s11>",
											"POSTING EVENT (G)",
											"WE LEFT state <s11>",
											"WE LEFT state <s1>",
											"WE ENTERED state <s2>",
											"WE ENTERED state <s21>",
											"WE ENTERED state <s211>",
											"POSTING EVENT (G)",
											"FINISHED TEST",
											"WE LEFT state <s211>",
											"WE LEFT state <s21>",
											"WE LEFT state <s2>",
											"WE LEFT state <s0>",
											"EVENT NOT HANDLED: [Event type=\"TEST COMPLETE\" bubbles=false cancelable=false eventPhase=2]"
											];
											
		private var allTransTypesOutput:Array = ["******** ENGINE EVENT ACTIVATE",
												"WE ENTERED state <s0>",
												"WE ENTERED state <s1>",
												"WE ENTERED state <s10>",
												"POSTING EVENT (a1)",
												"WE LEFT state <s10>",
												"WE ENTERED state <s10>",
												"POSTING EVENT (a2)",
												"WE LEFT state <s10>",
												"WE LEFT state <s1>",
												"WE ENTERED state <s1>",
												"WE ENTERED state <s10>",
												"POSTING EVENT (b1)",
												"WE LEFT state <s10>",
												"WE ENTERED state <s11>",
												"POSTING EVENT (c)",
												"EVENT NOT HANDLED: [Event type=\"c\" bubbles=false cancelable=false eventPhase=2]",
												"POSTING EVENT (d)",
												"WE LEFT state <s11>",
												"WE LEFT state <s1>",
												"WE ENTERED state <s1>",
												"WE ENTERED state <s10>",
												"POSTING EVENT (e)",
												"WE LEFT state <s10>",
												"WE ENTERED state <s11>",
												"POSTING EVENT (b2)",
												"WE LEFT state <s11>",
												"WE ENTERED state <s10>",
												"POSTING EVENT (f)",
												"WE LEFT state <s10>",
												"WE LEFT state <s1>",
												"WE ENTERED state <s2>",
												"WE ENTERED state <s21>",
												"POSTING EVENT (g)",
												"WE LEFT state <s21>",
												"WE LEFT state <s2>",
												"WE ENTERED state <s3>",
												"WE ENTERED state <s300>",
												"WE ENTERED state <s310>",
												"WE ENTERED state <s320>",
												"POSTING EVENT (b3)",
												"WE LEFT state <s320>",
												"WE ENTERED state <s321>",
												"WE LEFT state <s310>",
												"WE ENTERED state <s311>",
												"WE LEFT state <s300>",
												"WE ENTERED state <s301>",										
												"POSTING EVENT (h)",
												"WE LEFT state <s301>",
												"WE LEFT state <s311>",
												"WE LEFT state <s321>",
												"WE LEFT state <s3>",
												"WE ENTERED state <s1>",
												"WE ENTERED state <s10>",
												"POSTING EVENT (i)",
												"WE LEFT state <s10>",
												"WE LEFT state <s1>",
												"WE ENTERED state <s3>",
												"WE ENTERED state <s310>",
												"WE ENTERED state <s320>",
												"WE ENTERED state <s301>",
												"POSTING EVENT (h)",
												"WE LEFT state <s301>",
												"WE LEFT state <s310>",
												"WE LEFT state <s320>",
												"WE LEFT state <s3>",
												"WE ENTERED state <s1>",
												"WE ENTERED state <s10>",
												"POSTING EVENT (j)",
												"WE LEFT state <s10>",
												"WE LEFT state <s1>",
												"WE ENTERED state <s3>",
												"WE ENTERED state <s301>",
												"WE ENTERED state <s310>",
												"WE ENTERED state <s320>",
												"POSTING EVENT (b3)",
												"WE LEFT state <s320>",
												"WE ENTERED state <s321>",
												"WE LEFT state <s310>",
												"WE ENTERED state <s311>",
												"POSTING EVENT (k)",
												"WE LEFT state <s321>",
												"WE ENTERED state <s320>",
												"FINISHED TEST",
												"WE LEFT state <s301>",
												"WE LEFT state <s311>",
												"WE LEFT state <s320>",
												"WE LEFT state <s3>",
												"WE LEFT state <s0>",
												"******** ENGINE EVENT DEACTIVATE",
												"EVENT NOT HANDLED: [Event type=\"TEST COMPLETE\" bubbles=false cancelable=false eventPhase=2]"
		];
											
		private var tests:Array 		= [SamekTest, FirstMachine, allTransTypes ];
		private var testLogs:Array 		= [SamekTestOutput, FirstMachineOutput, allTransTypesOutput ];
		private var testLog:Array;
		private var testNames:Array 	= ["SAMEK TEST", "FIRST MACHINE", "ALL TRANSITION JUMPS"];
		private var currentTest:int 	= 0;
		private var numberOfTests:int 	= 3;
		
		public function Main():void 
		{	
			// ****************************************
			// Define state engine and network.
			// This is an example of declaring the topmost state in the StateEngine definition.
			
			OutputLog = [];
			testLog = testLogs[currentTest];
			trace("> RUNNING TEST " + testNames[currentTest]);
			tests[currentTest]();
		}
		
		private function finishTest () : void {
			var clean:Boolean = true, i:int = 0, failPt:int = 0;
			
			for (i = 0; i < testLog.length && i < OutputLog.length; i++) {
				if (OutputLog[i] != testLog[i]) {
					trace("** MACHINE TEST FAIL\n", "SHOULD BE: " + testLog[i] + "\nBUT OUTPUT IS: " + OutputLog[i] + "\n");
					clean = false;
					break;
				}
			}
			
			if (testLog.length != OutputLog.length) {
				trace("CURRENT LOG AND CORRECT LOG HAVE DIFFERENT # OF ELEMENTS.");
				clean = false;
			}
			
			if (clean) {
				trace("< PASSED: " + testNames[currentTest]);
				currentTest++;

				if (currentTest < numberOfTests) {
					OutputLog = [];
					trace("> RUNNING TEST " + testNames[currentTest]);
					testLog = testLogs[currentTest];
					tests[currentTest]();
					
				} else {
					trace("*** ALL TESTS COMPLETED SUCCESSFULLY.");
				}
			} else {
				failPt = i;
				trace(testNames[currentTest] + " FAILED\n", ">>>> HERE IS CURRENT LOG FROM FAILURE POINT:");
				for (; i < OutputLog.length; i++) {
					trace("     " + OutputLog[i]);
				}
				trace(">>>> HERE IS CORRECT LOG FROM FAILURE POINT:");
				for (i=failPt; i < testLog.length; i++) {
					trace("     " + testLog[i]);
				}
			}
		}
		
		private function addToLog (s:String) : void {
			OutputLog.push(s);
		}
		
		/* ******************************************************************* */
		
		public function EnterExitState (ev:Event) : void {
			addToLog("WE " + (ev.type == "ENTRY" ? "ENTERED" : "LEFT") + " state <"  + State(ev.target).name + ">");
		}
		
		public function NoHandle (ev:Event) : void {
			var givenEvent:Event = EventWithData(ev).data.event;
			if (givenEvent.type == "TEST COMPLETE") {
				se.active = false;
				
				addToLog("EVENT NOT HANDLED: " + givenEvent);
				finishTest();
			} else {
				addToLog("EVENT NOT HANDLED: " + givenEvent);
			}
		}
		
		public function EngineActive (ev:Event) : void {
			addToLog("******** ENGINE EVENT " + ev.type);
		}
		
		/* ******************************************************************* */
		
		private function SamekTest () : void {
			// Samek Engine test
				
			se	= new StateEngine("Samek02 Fig 4.3", new HState("s0"));
			
			se.addEventListener(StateEngine.UNHANDLED_EVENT, NoHandle);
			
			// Retrieving and storing the pointer to the topmost state
			var s0:HState   = HState(se.topState);
			s0.setDefaultStartState("s1");
			s0.addEventListener(State.ENTRY, EnterExitState);
			s0.addEventListener(State.LEAVE, EnterExitState);
			s0.addTransitionToTarget("Evt_e", "s211");
			// Set up a handler for events that go unhandled
			
			
			var s1:HState = s0.addSubHState("s1");
			s1.setDefaultStartState("s11");
			s1.addEventListener(State.ENTRY, EnterExitState);
			s1.addEventListener(State.LEAVE, EnterExitState);
			s1.addTransitionToSelf("Evt_a", null, 0);
			s1.addTransitionToTarget("Evt_b", "s11");
			s1.addTransitionToTarget("Evt_c", "s2");
			
			var s11:State = s1.addSubState("s11");
			s11.addEventListener(State.ENTRY, EnterExitState);
			s11.addEventListener(State.LEAVE, EnterExitState);
			s11.addTransitionToTarget("Evt_g", "s211");
			
			var s2:HState = s0.addSubHState("s2");
			s2.setDefaultStartState("s21");
			s2.addEventListener(State.ENTRY, EnterExitState);
			s2.addEventListener(State.LEAVE, EnterExitState);
			s2.addTransitionToTarget("Evt_f", "s11");
			
			var s21:HState = s2.addSubHState("s21");
			s21.setDefaultStartState("s211");
			s21.addEventListener(State.ENTRY, EnterExitState);
			s21.addEventListener(State.LEAVE, EnterExitState);
			
			var s211:State = s21.addSubState("s211");
			s211.addTransitionToTarget("Evt_d", "s21");
			s211.addTransitionToTarget("Evt_g", "s0");
			s211.addEventListener(State.ENTRY, EnterExitState);
			s211.addEventListener(State.LEAVE, EnterExitState);
			
			se.active = true;
			
			addToLog("POSTING EVENT (A)");
			se.postEvent(new Event("Evt_a"));
			
			addToLog("POSTING EVENT (B)");
			se.postEvent(new Event("Evt_b"));
			
			addToLog("POSTING EVENT (C)");
			se.postEvent(new Event("Evt_c"));
			
			addToLog("POSTING EVENT (D)");
			se.postEvent(new Event("Evt_d"));
			
			addToLog("POSTING EVENT (E)");
			se.postEvent(new Event("Evt_e"));
						
			addToLog("POSTING EVENT (F)");
			se.postEvent(new Event("Evt_f"));
			
			addToLog("POSTING EVENT (G)");
			se.postEvent(new Event("Evt_g"));
			
			addToLog("POSTING EVENT (G)");
			
			addToLog("FINISHED TEST");
			se.postEvent(new Event("TEST COMPLETE"));
		}
		
		
		
		private function FirstMachine () : void {
			/*
			 Initial machine test
			 */
			se	= new StateEngine("engine1", new HState("TOP_CONTAINER_STATE"));
	
			// Register handlers to react to StateEngine activation and deactivation
			se.addEventListener(StateEngine.ACTIVATE, EngineActive);
			se.addEventListener(StateEngine.DEACTIVATE, EngineActive);
			
			// Set up a handler for events that go unhandled
			se.addEventListener(StateEngine.UNHANDLED_EVENT, NoHandle);
			
			// Retrieving and storing the pointer to the topmost state
			var topContainerState:HState   = HState(se.topState);
			topContainerState.setDefaultStartState("ON");
			// Adding transitions and listeners to the topmost state.
			topContainerState.addTransitionToHistory("REALLY AFTER AFTER BOOGA-BOOGA", "ON", function ():void { addToLog("topContainerState transition to ON's History, Event: REALLY AFTER AFTER BOOGA-BOOGA"); } );		// If we get event REALLY AFTER AFTER BOOGA-BOOGA, go to state OFF1
			topContainerState.addEventListener(State.ENTRY, EnterExitState);
			topContainerState.addEventListener(State.LEAVE, EnterExitState);
			
			var offState:HState = topContainerState.addSubHState("OFF");
			offState.setDefaultStartState("OFF0");
		
			offState.addTransitionToTarget("BOOGA-BOOGA", "OFF1", function ():void { addToLog("OFF State to OFF1"); } );
			offState.addEventListener(State.ENTRY, EnterExitState);
			offState.addEventListener(State.LEAVE, EnterExitState);
			
			var off0State:State = offState.addSubState("OFF0");
			off0State.addEventListener(State.ENTRY, EnterExitState);
			off0State.addEventListener(State.LEAVE, EnterExitState);
			off0State.addTransitionToSelf("BOOGA-BOOGA", function ():void { addToLog("OFF0 Transition to Self (up and down 2 levels)"); }, 2);		// transition to self
			
			var off1State:State = offState.addSubState("OFF1");
			off1State.addEventListener(State.ENTRY, EnterExitState);
			off1State.addEventListener(State.LEAVE, EnterExitState);
			// Add a time-based pulse activity that fires every 2 seconds, approx.
			off1State.addPulseActivity(2000, statePulse);
			off1State.addTransitionToTarget("RANDOM", "ON1", function ():void { addToLog("OFF1 -> ON1 on Event: RANDOM"); } );
			
			// Create a concurrent hierarchical state.  We will need separate State Managers for each sub-network.
			var onState:HStateC	= topContainerState.addSubHStateC("ON");
			var onMgr0:StateManager = new StateManager("<ON MANAGER 0>", onState);
			var onMgr1:StateManager = new StateManager("<ON MANAGER 1>", onState);
			onState.setDefaultStartState("ON 0", onMgr0);
			onState.setDefaultStartState("ON5", onMgr1);
			onState.addEventListener(State.ENTRY, EnterExitState);
			onState.addEventListener(State.LEAVE, EnterExitState);
			
			// First sub-network, managed by <ON MANAGER 0>: states 0, 1, and 2
			
			var onState0:State	= onState.addSubState("ON 0", onMgr0);	// creates a sub-state of onState called ON 0 in the onMgr0 network
			onState0.addPulseActivity(40, statePulse, true);	// frame-based pulse activity
			onState0.addEventListener(State.ENTRY, EnterExitState);
			onState0.addEventListener(State.LEAVE, EnterExitState);
			
			onState0.addEventListener("RANDOM", CaughtEvent0);
			onState0.addTransitionToTarget("RANDOM5", "ON1", function ():void { addToLog("ON 0 -> ON1 on Event: RANDOM5"); } );
			
			var onState1:State	= onState.addSubState("ON1", onMgr0);	// creates a sub-state of onState called ON1 in the onMgr0 network
			onState1.addTransitionToTarget("BOOGA-BOOGA", "ON2", function ():void { addToLog("ON1 -> ON2 on Event: BOOGA-BOOGA"); } );
			onState1.addEventListener(State.ENTRY, EnterExitState);
			onState1.addEventListener(State.LEAVE, EnterExitState);
						
			var onState2:State	= onState.addSubState("ON2", onMgr0);	// creates a sub-state ofonState called ON2 in the onMgr0 network
			onState2.addEventListener(State.ENTRY, EnterExitState);
			onState2.addEventListener(State.LEAVE, EnterExitState);
			onState2.addTransitionToTarget("AFTER BOOGA-BOOGA", "OFF0", function ():void { addToLog("ON2 transition to OFF 0, Event: AFTER BOOGA-BOOGA"); } );
			
			// Second sub-network, managed by <ON MANAGER 1> state 5
			var onState5:State	= onState.addSubState("ON5", onMgr1);	// creates a sub-state of onState called ON5 in the onMgr1 network
			onState5.addEventListener(State.ENTRY, EnterExitState);
			onState5.addEventListener(State.LEAVE, EnterExitState);
			onState5.addEventListener("RANDOM5", CaughtEvent5);
		
	
			// ****************************************
			// activate network and send in some events
			se.active = true;
			
			se.postEvent(new Event("RANDOM"));				// handled by onState0.  During handling, we'll send another event, RANDOM5
			se.postEvent(new Event("BOOGA-BOOGA"), 2500);	// unhandled, but delayed by 5 seconds
			se.postEvent(new Event("AFTER BOOGA-BOOGA"));
			se.postEvent(new Event("REALLY AFTER AFTER BOOGA-BOOGA"), 1000);
			
			addToLog("FINISHED POSTING EVENTS");
			se.postEvent(new Event("TEST COMPLETE"));
		}
		
		public function statePulse (ev:Event) : void {
					addToLog("PULSE <" + State(EventWithData(ev).data.state).name + ">");
				}
				
		
		public function CaughtEvent0 (ev:Event) : void {
			addToLog("State <" + State(ev.target).name + "> Caught event: " + ev.type);
			se.postEvent(new Event("RANDOM5"), 2000);		// handled by onState5
		}
		
		public function CaughtEvent5 (ev:Event) : void {
			addToLog("State <" + State(ev.target).name + "> Caught event: " + ev.type);
		}
		
		
		private function allTransTypes () : void {
			se	= new StateEngine("allTransTypes", new HState("s0"));
	
			// Register handlers to react to StateEngine activation and deactivation
			se.addEventListener(StateEngine.ACTIVATE, EngineActive);
			se.addEventListener(StateEngine.DEACTIVATE, EngineActive);
			
			// Set up a handler for events that go unhandled.  For test cases, we need this because we handle TEST COMPLETE here.
			se.addEventListener(StateEngine.UNHANDLED_EVENT, NoHandle);
			
			var topContainerState:HState   = HState(se.topState);
			topContainerState.addEventListener(State.ENTRY, EnterExitState);
			topContainerState.addEventListener(State.LEAVE, EnterExitState);
			topContainerState.setDefaultStartState("s1");
			topContainerState.addTransitionToTarget("e", "s11");
			
			var s1:HState = topContainerState.addSubHState("s1");
			s1.setDefaultStartState("s10");
			s1.addTransitionToHistory("j", "s3");
			s1.addTransitionToTarget("i", "s301");
			s1.addEventListener(State.ENTRY, EnterExitState);
			s1.addEventListener(State.LEAVE, EnterExitState);

			var s10:State = s1.addSubState("s10");
			s10.addEventListener(State.ENTRY, EnterExitState);
			s10.addEventListener(State.LEAVE, EnterExitState);
			s10.addTransitionToSelf("a1");
			s10.addTransitionToSelf("a2", null, 1);
			s10.addTransitionToTarget("b1", "s11");
			s10.addTransitionToTarget("f", "s21");
			
			var s11:State = s1.addSubState("s11");
			s11.addEventListener(State.ENTRY, EnterExitState);
			s11.addEventListener(State.LEAVE, EnterExitState);
			s11.addTransitionToTarget("d", "s0");
			s11.addTransitionToTarget("b2", "s10");
			
			var s2:HState = topContainerState.addSubHState("s2");
			s2.addEventListener(State.ENTRY, EnterExitState);
			s2.addEventListener(State.LEAVE, EnterExitState);
			s2.setDefaultStartState("s20");
			
			var s20:State = s2.addSubState("s20");
			s20.addEventListener(State.ENTRY, EnterExitState);
			s20.addEventListener(State.LEAVE, EnterExitState);
			
			var s21:State = s2.addSubState("s21");
			s21.addEventListener(State.ENTRY, EnterExitState);
			s21.addEventListener(State.LEAVE, EnterExitState);
			s21.addTransitionToTarget("g", "s3");
			
			var s3:HStateC = topContainerState.addSubHStateC("s3");
			s3.addEventListener(State.ENTRY, EnterExitState);
			s3.addEventListener(State.LEAVE, EnterExitState);
			s3.addTransitionToTarget("h", "s1");
			
			var s3Mgr0:StateManager = new StateManager("<s3 MGR 0>", s3);
			
			var s300:State = s3.addSubState("s300", s3Mgr0);
			s300.addEventListener(State.ENTRY, EnterExitState);
			s300.addEventListener(State.LEAVE, EnterExitState);
			s300.addTransitionToTarget("b3", "s301");
			
			var s301:State = s3.addSubState("s301", s3Mgr0);
			s301.addEventListener(State.ENTRY, EnterExitState);
			s301.addEventListener(State.LEAVE, EnterExitState);
			
			s3.setDefaultStartState("s300", s3Mgr0);
			
			var s3Mgr1:StateManager = new StateManager("<s3 MGR 1>", s3);
			
			var s310:State = s3.addSubState("s310", s3Mgr1);
			s310.addEventListener(State.ENTRY, EnterExitState);
			s310.addEventListener(State.LEAVE, EnterExitState);
			s310.addTransitionToTarget("b3", "s311");
			
			var s311:State = s3.addSubState("s311", s3Mgr1);
			s311.addEventListener(State.ENTRY, EnterExitState);
			s311.addEventListener(State.LEAVE, EnterExitState);
			
			s3.setDefaultStartState("s310", s3Mgr1);
			
			var s3Mgr2:StateManager = new StateManager("<s3 MGR 2>", s3);
			s3.setDefaultStartState("s320", s3Mgr2);
			
			var s320:State = s3.addSubState("s320", s3Mgr2);
			s320.addEventListener(State.ENTRY, EnterExitState);
			s320.addEventListener(State.LEAVE, EnterExitState);
			s320.addTransitionToTarget("b3", "s321");
			
			var s321:State = s3.addSubState("s321", s3Mgr2);
			s321.addEventListener(State.ENTRY, EnterExitState);
			s321.addEventListener(State.LEAVE, EnterExitState);
			s321.addTransitionToHistory("k", "s3");
			
			se.active = true;
			
			addToLog("POSTING EVENT (a1)");
			se.postEvent(new Event("a1"));
			
			addToLog("POSTING EVENT (a2)");
			se.postEvent(new Event("a2"));
			
			addToLog("POSTING EVENT (b1)");
			se.postEvent(new Event("b1"));
					
			addToLog("POSTING EVENT (c)");
			se.postEvent(new Event("c"));
			
			addToLog("POSTING EVENT (d)");
			se.postEvent(new Event("d"));
			
			addToLog("POSTING EVENT (e)");
			se.postEvent(new Event("e"));
			
			addToLog("POSTING EVENT (b2)");
			se.postEvent(new Event("b2"));
						
			addToLog("POSTING EVENT (f)");
			se.postEvent(new Event("f"));
			
			addToLog("POSTING EVENT (g)");
			se.postEvent(new Event("g"));
			
			addToLog("POSTING EVENT (b3)");
			se.postEvent(new Event("b3"));
			
			addToLog("POSTING EVENT (h)");
			se.postEvent(new Event("h"));
			
			addToLog("POSTING EVENT (i)");
			se.postEvent(new Event("i"));
			
			addToLog("POSTING EVENT (h)");
			se.postEvent(new Event("h"));
			
			addToLog("POSTING EVENT (j)");
			se.postEvent(new Event("j"));
			
			addToLog("POSTING EVENT (b3)");
			se.postEvent(new Event("b3"));
			
			addToLog("POSTING EVENT (k)");
			se.postEvent(new Event("k"));
			
			addToLog("FINISHED TEST");
			se.postEvent(new Event("TEST COMPLETE"));
		}
	}
	
}